%% BEGIN pstricks.doc \def\fileversion{0.93a} \def\filedate{93/03/12} % File `pstricks.doc': PostScript macros for Generic TeX. %% See the PSTricks read-me file and the User's Guide for documentation. %% COPYRIGHT 1993, by Timothy Van Zandt, tvz@Princeton.EDU %% Copying of part or all of any file in the pstricks.tex package %% is allowed under the following conditions only: %% (1) You may freely distribute unchanged copies of the files. Please %% include the documentation when you do so. %% (2) You may modify a renamed copy of any file, but only for personal %% use or use within an organization. %% (3) You may copy fragments from the files, for personal use or for use %% in a macro package for distribution, as long as credit is given %% where credit is due. %% You are NOT ALLOWED to take money for the distribution or use of %% these files or modified versions or fragments thereof, except for %% a nominal charge for copying etc. % ************************************************************************** % This is `pstricks.doc', which contains the documented code for the PSTricks % package. See the PSTricks read-me file for information on how to % use this file. % ************************************************************************** % \EndDocPreamble % \CheckSum{5048} % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % \section{Disclaimers, Guidelines and Other Comments} % \paragraph*{Disclaimer} % These macros are extensive and were written hurriedly. Only modest attempts % have been made to clean up and optimize the code. The internals may change % substantially until version 1.0 comes up. % \paragraph*{PostScript Guidelines} % The following guidelines were followed for macros using PostScript % "\special"'s: % \begin{enumerate} % \item Almost no "gsave" and "grestore" commands are used (reducing the % likelihood of conflicts with dvi-to-ps drivers or an unmatched "gsave" or % "grestore" ending up on a page). % \item Most end-user macros (those without "@") have error-checking so that % bad arguments or other misuse will not generate PostScript errors. % \end{enumerate} % \iffalse % \paragraph*{Prefixes} % (This list is not complete.) Here are the conventions on prefixes, such as % the "pst" is "\pst@Verb": % \begin{center} % \begin{tabular}{ll} % {\em Prefix} & {\em Use}\\ % "pst" & This and that.\\ % "psk" & Graphics parameters ("k"={\em key}).\\ % "psset" & Macros that set graphics parameters.\\ % "psls" & Line styles.\\ % "psfs" & Fill styles.\\ % "psas" & Arrow styles.\\ % "pscs" & Custom styles.\\ % \end{tabular} % \end{center} % \fi % \paragraph*{Macros} % A ``macro'' means any command sequence that is documented in this with a % heading entry. Macros with "@" are internal, and others are part of the user % interface. Commands that are not in the heading preceding their definition % are internal commands of a macro, and are not meant to be used directly by % other macros. % \paragraph*{Local and global variables} % There are various classes of scratch registers and commands: % \begin{description} % \item[Global] These can be changed using "\global", etc. % \begin{LVerbatim} % \pst@tempg % \pst@temph % \pst@dimg % \pst@dimh % \pst@cntg % \pst@cnth % \pst@boxg % \end{LVerbatim} % \item[Local-I] These cannot be changed with "\global", but otherwise there % are no restrictions. % \begin{LVerbatim} % \next % \@tempa % \end{LVerbatim} % \item[Local-I] % Changes to these must be local to the macro in which they occur (be % grouping). % \begin{LVerbatim} % \pst@tempa % \pst@tempb % \pst@tempc % \pst@tempd % \end{LVerbatim} % \item[Local-II] Changes to these must be local to the macro in which they % occur, and it must be possible to use these as arguments of macros. % \begin{LVerbatim} % \pst@dima % \pst@dimb % \pst@dimc % \pst@dimd % \if@pst % \end{LVerbatim} % There is one exception. When using these in coordinates that are processed % directly as Cartesian coordinates rather than with "\pst@getcoor", they must % be used in this order: % \begin{LVerbatim} % (\pst@dima,\pst@dimb)(\pst@dimc,\pst@dimd) % \end{LVerbatim} % \item[Shared] These are used to share information between macros. Their % value may be set by one macro and then used by another. Use with care. Do % not set with "\global". % \begin{quote} % \begin{tabular}{ll} % \em command & \em usage\\ % "\pst@hbox" & Box created and manipulated in HR-box macros.\\ % "\pst@coor" & PostScript code for a coordinate.\\ % "\pst@angle" & PostScript code for an angle.\\ % "\pst@rot" & PostScript code for a rotation angle.\\ % "\if@star" & This is a flag to keep track of optional "*". % \end{tabular} % \end{quote} % \end{description} % \paragraph*{Plain \TeX\ commands} % The commands % \begin{LVerbatim} % \newbox % \newcount % \newdimen % \newif % \loop ... \repeat ... \fi % \z@ % \sixt@@n %\end{LVerbatim} % are defined in "plain.tex" are part of most macro packages. PSTricks assumes % that they are defined. Other than these, PSTricks only makes use of \TeX\ % primitives. % \paragraph*{Dividing the file} % {\bf\em Breaking up the file}\hskip 1em "pstricks.tex" can be broken up into % the following components: % \begin{description} % \item[Basics] (Including color and simple rotation.) Sections \ref{Prelim}, % \ref{Config}, \ref{Header}, \ref{Errors}, \ref{Colors}, \ref{Colortab}, % \ref{Rotation:simple} and \ref{Config:revisited}. % \item[Graphics] Sections \ref{Parameters}, \ref{Objects}, \ref{Linestyles}, % \ref{Arrowheads}, \ref{Lines}, \ref{Grids}, \ref{Fillstyles}, \ref{Frames}, % \ref{Frameboxes} and \ref{Circles}. Requires also {\bf Basics}. % \item[Rotation] (Including picture environment.) Sections \ref{Arithmetic}, % \ref{Rotation:prelim}, \ref{Rotation:main} and \ref{Pictures}. Requires also % {\bf Basics}. % \end{description} % \section{Preliminaries\label{Prelim}} % Check whether file has been loaded already. % \begin{macrocode} \csname PSTricksLoaded\endcsname \let\PSTricksLoaded\endinput % \end{macrocode} % Take care of the catcode of "@": % \begin{macrocode} \edef\PstAtCode{\the\catcode`\@} \catcode`\@=11\relax % \end{macrocode} % Here are some hacks borrowed from \LaTeX{}, which are defined if \LaTeX{} is % not being used. % \begin{macrocode} \expandafter\ifx\csname @latexerr\endcsname\relax \long\def\@ifundefined#1#2#3{\expandafter\ifx\csname #1\endcsname\relax#2\else#3\fi} \def\@namedef#1{\expandafter\def\csname #1\endcsname} \def\@nameuse#1{\csname #1\endcsname} \def\@eha{% Your command was ignored.^^J Type \space I \space to replace it with another command,^^J or \space \space to continue without it.} \def\@spaces{\space\space\space\space} \def\typeout#1{\immediate\write\@unused{#1}} \alloc@7\write\chardef\sixt@@n\@unused \def\@empty{} \def\@gobble#1{} \def\@nnil{\@nil} \def\@ifnextchar#1#2#3{% \let\@tempe#1\def\@tempa{#2}\def\@tempb{#3}\futurelet\@tempc\@ifnch} \def\@ifnch{% \ifx\@tempc\@sptoken \let\@tempd\@xifnch \else \ifx\@tempc\@tempe \let\@tempd\@tempa \else \let\@tempd\@tempb \fi \fi \@tempd} \begingroup \def\:{\global\let\@sptoken= } \: \def\:{\@xifnch} \expandafter\gdef\: {\futurelet\@tempc\@ifnch} \endgroup % \end{macrocode} % Announce that the file is being loaded: % \begin{macrocode} \typeout{`PSTricks' v\fileversion\space\space <\filedate> (tvz)} % \end{macrocode} % \section{Error messages} % \begin{macro}{\@pstrickserr} % "\@pstrickserr" is analogous to "\@latexerr". % \begin{macrocode} \def\@pstrickserr#1#2{% \begingroup \newlinechar`\^^J \edef\pst@tempc{#2}% \expandafter\errhelp\expandafter{\pst@tempc}% \typeout{% PSTricks error. \space See User's Guide for further information.^^J \@spaces\@spaces\@spaces\@spaces Type \space H \space for immediate help.}% \errmessage{#1}% \endgroup} % \end{macrocode} % \end{macro} % \begin{macro}{\@ehpa,\@ehpb,\@ehpc} % Here are some extra "\errhelp" message: % \begin{macrocode} \def\@ehpa{% Your command was ignored. Default value substituted.^^J Type \space \space to procede.} \def\@ehpb{% Your command was ignored. Will recover best I can.^^J Type \space \space to procede.} \def\@ehpc{% You better fix this before proceding.^^J See the PSTricks User's Guide or ask your system administrator for help.^^J Type \space X \space to quit.} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@misplaced} % \begin{macrocode} \def\pst@misplaced#1{\@pstrickserr{Misplaced \string#1 command}\@ehpb} % \end{macrocode} % \end{macro} % \section{Scratch registers} % \begin{macrocode} \newdimen\pst@dima \newdimen\pst@dimb \newdimen\pst@dimc \newdimen\pst@dimd \newdimen\pst@dimg \newdimen\pst@dimh \newbox\pst@hbox \newbox\pst@boxg \newcount\pst@cnta \newcount\pst@cntb \newcount\pst@cntc \newcount\pst@cntd \newcount\pst@cntg \newcount\pst@cnth \newif\if@pst % \end{macrocode} % \section{Useful hacks} % \begin{macro}{\pst@ifstar,\if@star} % \begin{macrocode} \newif\if@star \def\pst@ifstar#1{% \@ifnextchar*{\@startrue\def\next*{#1}\next}{\@starfalse#1}} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@expandafter} % \begin{macrocode} \def\pst@expandafter#1#2{% \def\next{#1}% \edef\@tempa{#2}% \ifx\@tempa\@empty \@pstrickserr{Unexpected empty argument!}\@ehpb \def\@tempa{\@empty}% \fi \expandafter\next\@tempa} % \end{macrocode} % \end{macro} % \section{Arithmetic} % \begin{macro}{\pst@dimtonum,\pst@@dimtonum} % This macro strips the value of "#1", a dimension register, of the "pt", and % assigns the result to "#2", a command sequence. This is used for arithmetic % and for converting \TeX\ dimensions to PostScript. % \begin{macrocode} \def\pst@dimtonum#1#2{\edef#2{\pst@@dimtonum#1}} \def\pst@@dimtonum#1{\expandafter\pst@@@dimtonum\the#1} {\catcode`\p=12 \catcode`\t=12 \global\@namedef{pst@@@dimtonum}#1pt{#1}} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@pyth} % This is a piecewise-linear approximation to $("#1"^2+"#2"^2)^(1/2)$. The % answer is assigned to "#3". All arguments should be dimension registers. % \begin{macrocode} \def\pst@pyth#1#2#3{% \ifdim#1>#2\pst@@pyth#1#2#3\else\pst@@pyth#2#1#3\fi} \def\pst@@pyth#1#2#3{% \ifdim4#1>9#2% #3=#1\advance#3 .2122#2% \else #3=.8384#1\advance#3 .5758#2% \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@divide} % This computes "#3"="#1"/"#2" reasonably quickly. "#1" and "#2" should be % dimensions, and "#3" should be a command sequence. % \begin{macrocode} \def\pst@divide#1#2#3{% \begingroup \pst@dimg=#1\relax\pst@dimh=#2\relax \pst@cnta=\pst@dimg \pst@cntb=1073741824 \pst@cntc=65536 \def\pst@tempa{\fi\ifnum}% \loop\ifnum\pst@cnta<\pst@cntb \pst@tempa\pst@cntc>\@ne \multiply\pst@cnta2\divide\pst@cntc2 \repeat \divide\pst@dimh\pst@cntc \divide\pst@cnta\pst@dimh \global\pst@dimg\number\pst@cnta sp \endgroup \pst@dimtonum\pst@dimg#3} % \end{macrocode} % \end{macro} % \section{Configuration file\label{Config}} % \begin{macro}{\pst@configerr} % \begin{macrocode} \def\pst@configerr#1{% \@pstrickserr{\string#1 not defined in pstricks.con}\@ehpc} % \end{macrocode} % \end{macro} % % \begin{macrocode} \def\pstVerb#1{\pst@configerr\pstVerb} \def\pstverb#1{\pst@configerr\pstverb} \def\pstverbscale{\pst@configerr\pstverbscale} \def\pstrotate{\pst@configerr\pstrotate} \def\pstheader#1{\pst@configerr\pstheader} \def\pstdriver{\pst@configerr\pstdriver} \@ifundefined{pstcustomize}% {\def\pstcustomize{\endinput\let\pstcustomize\relax}}{} \input pstricks.con % \end{macrocode} % \begin{macro}{\PSTricksOff} % \begin{macrocode} \newif\ifPSTricks \PSTrickstrue \def\PSTricksOff{% \def\pstheader##1{}% \def\pstverb##1{}% \def\pstVerb##1{}% \PSTricksfalse} % \end{macrocode} % \end{macro} % \section{PostScript header file\label{Header}} % \begin{macro}{\pst@def,\pst@ATH,\pst@useheader} % There are three ways to use PSTricks: % \begin{enumerate} % \item Use "pstricks.doc" directly. No header file is used. % \item Use "\pst-make.tex" to generate a stripped input file for use without % a header. % \item Use "\pst-make.tex" to generate a header and a stripped input file for % use with the header. % \end{enumerate} % PSTricks has been optimized for use with a header file (and the difference % is speed and memory is very significant), but the flexible system described % above makes it easier to maintain the code and allows one to use PSTricks % with a DVI-to-PS driver that does not support header files. % The following commands should be used in this ".doc" file for PostScript % macros and other goodies related to the header file. Their behavior for each % of the three cases list above is given below. These commands should always % come {\em at the beginning of the line}, and should not inside conditionals. % \begin{itemize} % \item "\pst@def{foo}" % \begin{enumerate} % \item "\tx@foo" is defined to be "bar". % \item Writes % \begin{LVerbatim} % \def\tx@foo{bar} % \end{LVerbatim} % to "pstricks.tex". % \item Writes % \begin{LVerbatim} % /foo { bar } def % \end{LVerbatim} % to "pstricks.pro" and % \begin{LVerbatim} % \def\tx@foo{foo} % \end{LVerbatim} % to "pstricks.tex". % \end{enumerate} % \item "\pst@ATH" % \begin{enumerate} % \item Gobbles "foo". % \item Ignores line. % \item Writes "foo" to "pstricks.pro". % \end{enumerate} % Note: "\pst@ATH" must come at the beginning of the line. % \item "\ifx\pst@useheader\iftrue foo \else bar \fi" % \begin{enumerate} % \item Ignores "foo" and includes "bar". % \item Ignores "foo" and processes "bar". % \item Processes "foo" and ignores "bar". % \end{enumerate} % Note: "\ifx\pst@useheader\iftrue", "\else" and "\fi" must each be on their % own line. % \end{itemize} % "pst@make.tex" can be used to process other files at well, in the right % order. % \begin{macrocode} \@ifundefined{pst@def}{\def\pst@def#1<#2>{\@namedef{tx@#1}{#2 }}}{} \@ifundefined{pst@ATH}{\def\pst@ATH<#1>{}}{} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@dict} % The PostScript dictionary "tx@Dict" is set up in the header file, if one is % used. Otherwise, it is set up with each procedure that uses the dictionary, % if it is not currently defined. % \begin{macrocode} \pst@ATH<\% Version \fileversion, \filedate.> \pst@ATH<\% For use with \pstdriver.> \pst@ATH \pst@ATH \pst@ATH \pst@ATH \pst@ATH \pst@ATH \pst@ATH \pst@ATH \pst@ATH \ifx\pst@useheader\iftrue \pstheader{pstricks.pro} \def\pst@dict{tx@Dict begin } \def\pst@theheaders{pstricks.pro} \else \def\pst@dict{% /tx@Dict where { pop tx@Dict begin} { userdict begin /tx@Dict 200 dict def end tx@Dict begin /ADict 25 dict def /CM { matrix currentmatrix } bind def /SLW /setlinewidth load def /CLW /currentlinewidth load def /CP /currentpoint load def /ED { exch def } bind def /L /lineto load def } ifelse } \def\pst@theheaders{}% % \end{macrocode} % \end{macro} % \begin{macro}{\pst@Verb} % \begin{macrocode} \def\pst@Verb#1{\pstVerb{\pst@dict #1 end}} % \end{macrocode} % \end{macro} % \section{PostScript hacks} % \begin{macro}{\tx@Atan,\tx@Div} % These are variants of "atan", and "div", that recover when result is not % defined. % \begin{macrocode} \pst@def{Atan} \pst@def{Div} % \end{macrocode} % \end{macro} % \begin{macro}{\tx@NET} % \begin{macrocode} \pst@def{NET} % \end{macrocode} % \end{macro} % \begin{macro}{\tx@Pyth} % $A$ $B$ "Pyth" $(A^2 + B^2)^{1/2}$ % \begin{macrocode} \pst@def{Pyth} % \end{macrocode} % \end{macro} % \begin{macro}{\tx@PtoC} % Polar to Cartesian: % \begin{LVerbatim} % PtoC % \end{LVerbatim} % \begin{macrocode} \pst@def{PtoC}<2 copy cos mul 3 1 roll sin mul> % \end{macrocode} % \end{macro} % \begin{macro}{\tx@PathLength} % "PathLength" is taken from the Blue Book. It leaves on the stack the length % of the current path. % \begin{macrocode} \pst@def{PathLength@}<% /z z y y1 sub x x1 sub \tx@Pyth add def /y1 y def /x1 x def> \pst@def{PathLength}<% flattenpath /z 0 def { /y1 ED /x1 ED /y2 y1 def /x2 x1 def } % moveto { /y ED /x ED \tx@PathLength@ } % lineto {} % curveto; ignore because of flattenpath. { /y y2 def /x x2 def \tx@PathLength@ } % closepath pathforall z> % \end{macrocode} % \end{macro} % \section{Converting \TeX\ things to PostScript} % \begin{macro}{\pst@number,\tx@STP,\tx@STV} % \begin{itemize} % \item PSTricks' PostScript unit is 1pt, rather than 1bp, because this is % more efficient. % \item "\pst@number{}" converts to PostScript, in % points (pt). % \item "\tx@STP" scales the DVI-to-PS driver's "\pstverb" environment to % points (pt). % \item "\tx@STV" scales the DVI-to-PS drivers's ungrouped PostScript % "\special" environment ("\pstVerb") to points (pt). % \end{itemize} % \begin{macrocode} \pst@dimg=\pstunit\relax \ifdim\pst@dimg=1bp \def\pst@stp{.996264 dup scale} \else \edef\pst@stp{1 \pst@@dimtonum\pst@dimg\space div dup scale} \pst@def{STP}<\pst@stp> \pst@def{STV}<\pstverbscale\space\tx@STP> \def\pst@number#1{\pst@@dimtonum#1\space} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@checknum} % The first argument of "\pst@checknum" should be a number, and the second % argument is a command. There are three possible outcomes: % \begin{enumerate} % \item The number is suitable for PostScript consumption, the command is set % to the number, and "\pst@num" is set to "1" if the number is positive and to % "2" if the number is negative. % \item "\pst@checknum" detects that the number is not suitable for % PostScript; "\pst@num" is set to "0", an error is given, and the command is % defined to be {\tt 0 }. % \item The number is not suitable for PostScript consumption, but % "\pst@checknum" does not detect this. "\pst@num" is set to "1" or "2", and % the command is set to some number that {\em is} suitable for PostScript. % \end{enumerate} % A trailing space is always added. % "\pst@checknum" should generate no extraneous errors nor output, even if the % first argument is a bad number. % This macro is probably pretty close to optimal for what it does, as many % variations have been tried. % \begin{macrocode} \def\pst@checknum#1#2{% \edef\next{#1}% \ifx\next\@empty \let\pst@num\z@ \else \expandafter\pst@@checknum\next..\@nil \fi \ifnum\pst@num=\z@ \@pstrickserr{Bad number: `#1'. 0 substituted.}\@ehpa \def#2{0 }% \else \edef#2{\ifnum\pst@num=2 -\fi\the\pst@cntg.% \expandafter\@gobble\the\pst@cnth\space}% \fi} \def\pst@@checknum{% \@ifnextchar-% {\def\pst@num{2}\expandafter\pst@@@checknum\@gobble}% {\def\pst@num{1}\pst@@@checknum}} \def\pst@@@checknum#1.#2.#3\@nil{% \afterassignment\pst@@@@checknum\pst@cntg=0#1\relax\@nil \afterassignment\pst@@@@checknum\pst@cnth=1#2\relax\@nil} \def\pst@@@@checknum#1\relax\@nil{% \ifx\@nil#1\@nil\else\let\pst@num\z@\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@getnumii,\pst@getnumiii,\pst@getnumiv} % These are for processing comma-separated lists of numbers. They assign the % numbers to "\pst@tempg", "\pst@temph", etc. Use like % \begin{LVerbatim} % \pst@expandafter\pst@getnumiii{foo} {} {} {} {}\@ni % \end{LVerbatim} % If there are too few numbers, an error results. If there are too many, the % extra numbers are ignored. % \begin{macrocode} \def\pst@getnumii#1 #2 #3\@nil{% \pst@checknum{#1}\pst@tempg \pst@checknum{#2}\pst@temph} \def\pst@getnumiii#1 #2 #3 #4\@nil{% \pst@checknum{#1}\pst@tempg \pst@checknum{#2}\pst@temph \pst@checknum{#3}\pst@tempi} \def\pst@getnumiv#1 #2 #3 #4 #5\@nil{% \pst@checknum{#1}\pst@tempg \pst@checknum{#2}\pst@temph \pst@checknum{#3}\pst@tempi \pst@checknum{#4}\pst@tempj} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@getdimnum} % Like "\pst@getnumii", but first item is a dimension and second is a number. % \begin{macrocode} \def\pst@getdimnum#1 #2 #3\@nil{% \pssetlength\pst@dimg{#1}% \pst@checknum{#2}\pst@tempg} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@getscale} % "\pst@getscale" can have one or two numbers in its first argument. % \begin{macrocode} \def\pst@getscale#1#2{% \pst@expandafter\pst@getnumii{#1 #1} {} {} {}\@nil \edef#2{\pst@tempg\space \pst@temph\space scale }% \ifdim\pst@tempg\p@=\z@ \@pstrickserr{Bad scaling argument `#1'}\@ehpa \def#2{}% \else \ifdim\pst@temph\p@=\z@ \@pstrickserr{Bad scaling argument}\@ehpa \def#2{}% \else \ifdim\pst@tempg\p@=\p@ \ifdim\pst@temph\p@=\p@ \def#2{}\fi\fi \fi \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@getint} % \begin{macrocode} \def\pst@getint#1#2{% \pst@cntg=#1\relax \edef#2{\the\pst@cntg\space}} % \end{macrocode} % \end{macro} % \begin{macro}{\pslbrace,\psrbrace} % When balanced braces are used, they work without problems in "\special"'s. % "\pslbrace" and "\psrbrace" let you use unbalanced braces. % \begin{macrocode} \begingroup \catcode`\{=12 \catcode`\}=12 \catcode`\[=1 \catcode`\]=2 \gdef\pslbrace[{ ] \gdef\psrbrace[} ] \endgroup % \end{macrocode} % \end{macro} % \section{Colors\label{Colors}} % \begin{macro}{\@newcolor} % "\@newcolor{}{}", where is a name and is the % associated PostScript color specification , sets % \begin{itemize} % \item "\" to "\pst@color{}", and % \item "\color@" to . % \end{itemize} % Then "\" can be used by the user to color text, etc., and % "\color@" is used by PSTricks graphics objects to find the % specification for . % \begin{macrocode} \def\@newcolor#1#2{% \expandafter\edef\csname #1\endcsname{\noexpand\pst@color{#2}}% \expandafter\edef\csname color@#1\endcsname{#2}% \ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@color,\pst@endcolor} % The argument of "\pst@color" should be a PostScript command for setting the % color; e.g., "0 setgray". It saves the command in "\pst@currentcolor", and % then switches to "\pst@currentcolor" at the end of the current group. The % color changes do not extend across pages, although this capability could be % written into the output routines (so that "\pst@currentcolor" is set at the % beginning of the page, and headers and footers begin with "\black", etc.). % Moving boxes cause problems, but there is no way around this until \TeX{} % supports color internally. % \begin{macrocode} \def\pst@color#1{% \def\pst@currentcolor{#1}\pstVerb{#1}\aftergroup\pst@endcolor} \def\pst@endcolor{\pstVerb{\pst@currentcolor}} \def\pst@currentcolor{0 setgray} % \end{macrocode} % \end{macro} % \begin{macro}{\altcolormode,\pst@grestore} % The color macros defined above can conflict with other color macros. % "\altcolormode" sets up a different scheme that uses "gsave" and "grestore" % to reset colors. This may reduce the likelihood of such conflict. It also % makes moving boxes less of a problem, as long as the color command is itself % grouped within the box. However, if the scope of a color command extends % across pages in a \TeX{} input file, unmatched "gsave"'s and "grestore"'s % will be left on pages, wreaking havok on the output. "\pst@grestore" is % defined to do various things that makes using "grestore" more robust. % \begin{macrocode} \def\altcolormode{% \def\pst@color##1{% \pstVerb{gsave ##1}\aftergroup\pst@endcolor}% \def\pst@endcolor{\pstVerb{\pst@grestore}}} \def\pst@grestore{% currentpoint matrix currentmatrix currentfont grestore setfont setmatrix moveto} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@usecolor} % This looks up the color specification. % \begin{macrocode} \def\pst@usecolor#1{\csname color@#1\endcsname\space} % \end{macrocode} % \end{macro} % \begin{macro}{\newgray} % "\newgray" uses PostScript's "setgray" operator. % \begin{macrocode} \def\newgray#1#2{% \pst@checknum{#2}\pst@tempg \@newcolor{#1}{\pst@tempg setgray}} % \end{macrocode} % \end{macro} % \begin{macro}{\newrgbcolor} % This works like "\newgray", but the color specification should consist of 3 % numbers rather than just 1, and the "setrgbcolor" operator is used. % \begin{macrocode} \def\newrgbcolor#1#2{% \pst@expandafter\pst@getnumiii{#2} {} {} {} {}\@nil \@newcolor{#1}{\pst@tempg \pst@temph \pst@tempi setrgbcolor}} % \end{macrocode} % \end{macro} % \begin{macro}{\newhsbcolor} % This is just like "\newrgbcolor", but the "sethsbcolor" operator is used. % \begin{macrocode} \def\newhsbcolor#1#2{% \pst@expandafter\pst@getnumiii{#2} {} {} {} {}\@nil \@newcolor{#1}{\pst@tempg \pst@temph \pst@tempi sethsbcolor}} % \end{macrocode} % \end{macro} % \begin{macro}{\newcmykcolor} % This is like "\newrgbcolor", the color specification consists of 4 numbers % and the "setcmykcolor" operator is used. % \begin{macrocode} \def\newcmykcolor#1#2{% \pst@expandafter\pst@getnumiv{#2} {} {} {} {} {}\@nil \@newcolor{#1}{\pst@tempg \pst@temph \pst@tempi \pst@tempj setcmykcolor}} % \end{macrocode} % \end{macro} % \begin{macro}{\black,\darkgray,\gray,\lightgray,\white} % Here are some default gray definitions: % \begin{macrocode} \newgray{black}{0} \newgray{darkgray}{.25} \newgray{gray}{.5} \newgray{lightgray}{.75} \newgray{white}{1} % \end{macrocode} % \end{macro} % \begin{macro}{\red,\green,\blue,\yellow,\cyan,\magenta} % And some default rgb color definitions. % \begin{macrocode} \newrgbcolor{red}{1 0 0} \newrgbcolor{green}{0 1 0} \newrgbcolor{blue}{0 0 1} \newrgbcolor{yellow}{1 1 0} \newrgbcolor{cyan}{0 1 1} \newrgbcolor{magenta}{1 0 1} % \end{macrocode} % \end{macro} % \section{Setting graphics parameters\label{Parameters}} % \begin{macro}{\psset} % For each "=" pair in its argument, "\psset" invokes % \begin{LVerbatim} % \psset@{} % \end{LVerbatim} % The value is processed and typically stored in "\ps" if the % value is user-accessible and "\psk@" if not. "\psset" ignores % spaces that follow the comma that separates key-value pairs. % When initializing in this file, preferable use % \begin{LVerbatim} % \psset@{} % \end{LVerbatim} % so that default values can be easily extracted for the {\em User's Guide}. % \begin{macrocode} \def\psset#1{\@psset#1,\@nil\ignorespaces} \def\@psset#1,{% \@@psset#1==\@nil \@ifnextchar\@nil{\@gobble}{\@psset}} \def\@@psset#1=#2=#3\@nil{% \@ifundefined{psset@#1}% {\@pstrickserr{Graphics parameter `#1' not defined.}\@ehpa}% {\@nameuse{psset@#1}{#2}}}% % \end{macrocode} % \end{macro} % \begin{macro}{\newpsstyle} % \begin{macrocode} \def\psset@style#1{% \@ifundefined{pscs@#1}% {\@pstrickserr{Custom style `#1' undefined}\@ehpa}% {\@nameuse{pscs@#1}}} \def\newpsstyle#1#2{\@namedef{pscs@#1}{\psset{#2}}} % \end{macrocode} % \end{macro} % \begin{macro}{\@none} % Use to check when a parameter value is "none". % \begin{macrocode} \def\@none{none} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@getcolor} % This is used by various graphics parameters that are colors. % \begin{macrocode} \def\pst@getcolor#1#2{% \@ifundefined{color@#1}% {\@pstrickserr{Color `#1' not defined}\@eha}% {\edef#2{#1}}} % \end{macrocode} % \end{macro} % \section{Dimensions} % \begin{macro}{\psunit,\psxunit,\psyunit} % \begin{macrocode} \newdimen\psunit \psunit 1cm \newdimen\psxunit \psxunit 1cm \newdimen\psyunit \psyunit 1cm \let\psrunit\psunit % \end{macrocode} % \end{macro} % \begin{macro}{\pssetlength,\psaddtolength,\pssetxlength,\pssetylength} % \begin{macrocode} \def\pstunit@off{\let\@psunit\ignorespaces\ignorespaces} \def\pssetlength#1#2{% \let\@psunit\psunit \afterassignment\pstunit@off #1 #2\@psunit} \def\psaddtolength#1#2{% \let\@psunit\psunit \afterassignment\pstunit@off \advance#1 #2\@psunit} \def\pssetxlength#1#2{% \let\@psunit\psxunit \afterassignment\pstunit@off #1 #2\@psunit} \def\pssetylength#1#2{% \let\@psunit\psyunit \afterassignment\pstunit@off #1 #2\@psunit} % \end{macrocode} % \end{macro} % \begin{macro}{\psset@unit,\psset@xunit,\psset@yunit} % \begin{macrocode} \def\psset@unit#1{% \pssetlength\psunit{#1}% \psxunit=\psunit \psyunit=\psunit} \def\psset@runit#1{\pssetlength\psrunit{#1}} \def\psset@xunit#1{\pssetxlength\psxunit{#1}} \def\psset@yunit#1{\pssetylength\psyunit{#1}} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@getlength,pst@@getlength} % "#1" is a \TeX\ dimensions. "\pst@getlength" sets "#2" to the PostScript % code for "#1", and "\pst@@getlength" set "#2" to the \TeX\ code for "#1". % \begin{macrocode} \def\pst@getlength#1#2{% \pssetlength\pst@dimg{#1}% \edef#2{\pst@number\pst@dimg}} \def\pst@@getlength#1#2{% \pssetlength\pst@dimg{#1}% \edef#2{\number\pst@dimg sp}} % \end{macrocode} % \end{macro} % \section{Normal Coordinates and angles} % \begin{macro}{\pst@getcoor,\pst@coor} % "\pst@@getcoor" should be defined to read a coordinate and convert it to % PostScript, assigning the result to "\pst@coor" (including the trailing % space). % "\pst@getcoor" invokes "\pst@@getcoor" and then sets its second argument to % "\pst@coor". % \begin{macrocode} \def\pst@getcoor#1#2{\pst@@getcoor{#1}\let#2\pst@coor} \def\pst@coor{0 0 } % \end{macrocode} % \end{macro} % \begin{macro}{\pst@getcoors,\pst@coors} % "\pst@getcoors" reads coordinates until there are none left, adding them % {\em in reverse order} to "\pst@coors". % \begin{macrocode} \def\pst@getcoors#1#2{% \def\pst@aftercoors{\addto@pscode{#1 \pst@coors }#2}% \def\pst@coors{}% \pst@@getcoors} \def\pst@@getcoors(#1){% \pst@@getcoor{#1}% \edef\pst@coors{\pst@coor\pst@coors}% \@ifnextchar({\pst@@getcoors}{\pst@aftercoors}} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@getangle,\pst@angle} % \n\pst@@getangle\ should be defined to read an angle and convert it to % PostScript, assigning the result to \n\pst@angle\ (including the trailing % space). % \n\pst@getangle\ invokes \n\pst@@getangle\ and then sets its second argument % to \n\pst@angle. % \begin{macrocode} \def\pst@getangle#1#2{\pst@@getangle{#1}\let#2\pst@angle} \def\pst@angle{0 } % \end{macrocode} % \end{macro} % \begin{macro}{getcoor@c,\NormalCoor} % By default, coordinates are read as Cartesian coordinates by % "\cartesian@coor". % Angles are read as numbers, scaled by \n\pst@angleunit. % "\NormalCoor" sets these two defaults, and also defines the translation for % the put commands to be done by \TeX\ using Cartesian coordinates. % \begin{macrocode} \def\cartesian@coor#1,#2,#3\@nil{% \pssetxlength\pst@dimg{#1}% \pssetylength\pst@dimh{#2}% \edef\pst@coor{\pst@number\pst@dimg \pst@number\pst@dimh}} \def\NormalCoor{% \def\pst@@getcoor##1{\pst@expandafter\cartesian@coor{##1},\relax,\@nil}% \def\pst@@getangle##1{% \pst@checknum{##1}\pst@angle \edef\pst@angle{\pst@angle \pst@angleunit}}% \def\psput@##1{\pst@@getcoor{##1}\leavevmode\psput@cartesian}} \NormalCoor % \end{macrocode} % \end{macro} % \begin{macro}{\pst@angleunit,\degrees,\radians} % "\degrees" sets "\pst@angleunit" to the PostScript code for scaling the % angle, including the trailing space. % \begin{macrocode} \def\degrees{\@ifnextchar[{\@degrees}{\def\pst@angleunit{}}} \def\@degrees[#1]{% \pst@checknum{#1}\pst@tempg \edef\pst@angleunit{360 \pst@tempg div mul }% \ignorespaces} \def\radians{\def\pst@angleunit{57.2956 mul }} \def\pst@angleunit{} % \end{macrocode} % \end{macro} % \section{Special coordinates and angles} % This is a tedious but useful. % \begin{macro}{\SpecialCoor} % \begin{macrocode} \def\SpecialCoor{% \def\pst@@getcoor##1{\pst@expandafter\special@coor{##1}||\@nil}% \def\pst@@getangle##1{\pst@expandafter\special@angle{##1}\@empty)\@nil}% \def\psput@##1{\pst@@getcoor{##1}\leavevmode\psput@special}} % \end{macrocode} % \end{macro} % \begin{macro}{\specialcoor} % \begin{macrocode} \def\special@coor#1|#2|#3\@nil{% \ifx#3|\relax \mixed@coor{#1}{#2}% \else \special@@coor#1;;\@nil \fi} \def\special@@coor#1{% \ifcat#1a\relax \def\next{\node@coor#1}% \else \ifx#1[\relax \def\next{\Node@coor[}% \else \ifx#1!\relax \def\next{\raw@coor}% \else \def\next{\special@@@coor#1}% \fi \fi \fi \next} \def\special@@@coor#1;#2;#3\@nil{% \ifx#3;\relax \polar@coor{#1}{#2}% \else \cartesian@coor#1,\relax,\@nil \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\mixed@coor} % This allows mixing of coordinate types with \n\SpecialCoor. % \begin{macrocode} \def\mixed@coor#1#2{% \begingroup \specialcoor@ii#1;;\@nil \let\pst@tempa\pst@coor \specialcoor@ii#2;;\@nil \xdef\pst@tempg{\pst@tempa pop \pst@coor exch pop }% \endgroup \let\pst@coor\pst@tempg} % \end{macrocode} % \end{macro} % \begin{macro}{\polar@coor} % For polar coordinates % \begin{macrocode} \def\polar@coor#1#2{% \pssetlength\pst@dimg{#1}% \pst@@getangle{#2}% \edef\pst@coor{\pst@number\pst@dimg \pst@angle \tx@PtoC}} % \end{macrocode} % \end{macro} % \begin{macro}{\raw@coor} % For raw PostScript. % \begin{macrocode} \def\raw@coor#1;#2\@nil{% \edef\pst@coor{% #1 \pst@number\psyunit mul exch \pst@number\psxunit mul exch }} % \end{macrocode} % \end{macro} % \begin{macro}{\node@coor,\Node@coor} % These are defined in "pst-node.tex". % \begin{macrocode} \def\node@coor#1\@nil{% \@pstrickserr{You must load `pst-node.tex' to use node coordinates.}\@ehps \def\pst@coor{0 0 }} \def\Node@coor{\node@coor} % \end{macrocode} % \end{macro} % \begin{macro}{\special@angle} % \begin{macrocode} \def\special@angle#1#2)#3\@nil{% \ifx#1!\relax \edef\pst@angle{#2 \pst@angleunit}% \else \ifx#1(\relax \pst@@getcoor{#2}% \edef\pst@angle{\pst@coor exch \tx@Atan}% \else \pst@checknum{#1#2}\pst@angle \edef\pst@angle{\pst@angle \pst@angleunit}% \fi \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\Cartesian,\Polar} % These are obsolete. % \begin{macrocode} \def\Cartesian{% \def\cartesian@coor##1,##2,##3\@nil{% \pssetxlength\pst@dimg{##1}% \pssetylength\pst@dimh{##2}% \edef\pst@coor{\pst@number\pst@dimg \pst@number\pst@dimh}}% \@ifnextchar({\Cartesian@}{}} \def\Cartesian@(#1,#2){% \pssetxlength\psxunit{#1}% \pssetylength\psyunit{#2}% \ignorespaces} \def\Polar{% \def\psput@cartesian{\psput@special}% \def\cartesian@coor##1,##2,##3\@nil{\polar@coor{##1}{##2}}}% % \end{macrocode} % \end{macro} % \section{Basic graphics parameters} % \begin{macro}{\psset@origin,\psk@origin} % \begin{macrocode} \def\psset@origin#1{% \pst@@getcoor{#1}% \edef\psk@origin{\pst@coor \tx@NET }} \def\psk@origin{} % \end{macrocode} % \end{macro} % \begin{macro}{\psset@swapaxes,\ifpsswapaxes} % \begin{macrocode} \newif\ifswapaxes \def\psset@swapaxes#1{% \@nameuse{@pst#1}% \if@pst \def\psk@swapaxes{-90 rotate -1 1 scale }% \else \def\psk@swapaxes{}% \fi} \psset@swapaxes{false} % \end{macrocode} % \end{macro} % \begin{macro}{\psset@showpoints,\ifshowpoints} % \begin{macrocode} \newif\ifshowpoints \def\psset@showpoints#1{\@nameuse{showpoints#1}} \psset@showpoints{false} % \end{macrocode} % \end{macro} % \begin{macro}{\psset@border,\psk@border} % \begin{macrocode} \let\pst@setrepeatarrowsflag\relax \def\psset@border#1{% \pst@getlength{#1}\psk@border \pst@setrepeatarrowsflag} \psset@border{0pt} % \end{macrocode} % \end{macro} % \begin{macro}{\psset@bordercolor,\psbordercolor} % \begin{macrocode} \def\psset@bordercolor#1{\pst@getcolor{#1}\psbordercolor} \psset@bordercolor{white} % \end{macrocode} % \end{macro} % \begin{macro}{\psset@doubleline,\ifpsdoubleline} % \begin{macrocode} \newif\ifpsdoubleline \def\psset@doubleline#1{% \@nameuse{psdoubleline#1}% \pst@setrepeatarrowsflag} \psset@doubleline{false} % \end{macrocode} % \end{macro} % \begin{macro}{\psset@doublesep,\psdoublesep} % \begin{macrocode} \def\psset@doublesep#1{\def\psdoublesep{#1}} \psset@doublesep{1.25\pslinewidth} % \end{macrocode} % \end{macro} % \begin{macro}{\psset@doublecolor,\psdoublecolor} % \begin{macrocode} \def\psset@doublecolor#1{\pst@getcolor{#1}\psdoublecolor} \psset@doublecolor{white} % \end{macrocode} % \end{macro} % \begin{macro}{\psset@shadow,\ifpsshadow} % \begin{macrocode} \newif\ifpsshadow \def\psset@shadow#1{% \@nameuse{psshadow#1}% \pst@setrepeatarrowsflag} \psset@shadow{false} % \end{macrocode} % \end{macro} % \begin{macro}{\psset@shadowsize,\psk@shadowsize} % \begin{macrocode} \def\psset@shadowsize#1{\pst@getlength{#1}\psk@shadowsize} \psset@shadowsize{3pt} % \end{macrocode} % \end{macro} % \begin{macro}{\psset@shadowangle,\psk@shadowangle} % \begin{macrocode} \def\psset@shadowangle#1{\pst@getangle{#1}\psk@shadowangle} \psset@shadowangle{-45} % \end{macrocode} % \end{macro} % \begin{macro}{\psset@shadowcolor,\psshadowcolor} % \begin{macrocode} \def\psset@shadowcolor#1{\pst@getcolor{#1}\psshadowcolor} \psset@shadowcolor{darkgray} % \end{macrocode} % \end{macro} % \begin{macro}{\pst@setrepeatarrowsflag} % \begin{macrocode} \def\pst@repeatarrowsflag{\z@} \def\pst@setrepeatarrowsflag{% \edef\pst@repeatarrowsflag{% \ifdim\psk@border\p@>\z@ 1\else\ifpsdoubleline 1\else \ifpsshadow 1\else \z@\fi\fi\fi}} % \end{macrocode} % \end{macro} % \section{Line styles\label{Linestyles}} % For each "linestyle"